---
title: Веб-сервер Nginx на Debian з LetsEncrypt HTTPS і Certbot
x-toc-enable: true
...

Вступ
============

Розміщення веб-сайту - це обряд з 1990-х років для тих, хто хоче
справді мати право голосу в інтернеті. Це можна зробити недорого, на
загальнодоступному обладнанні. Будь-яка пристойна операційна система (наприклад,
FreeBSD, OpenBSD, Linux дистрибутиви) може легко запускати веб-сервер, і існує
багато серверів (nginx, lighttpd, Apache, власний *httpd* OpenBSD та інші).

Цей посібник навчить вас, як налаштувати захищений веб-сервер у [Debian
Linux](https://www.debian.org/), використовуючи nginx. Ми будемо використовувати
*Let's Encrypt* як наш центр сертифікації, дозволяючи використовувати шифрування
через URL-адреси `https://` з прослуховуванням nginx на порту 443.

Let's Encrypt - це некомерційний центр сертифікації, яким керує
[Internet Security Research Group](https://www.abetterinternet.org/). Ви
можете дізнатися більше про Let's Encrypt на їх веб-сайті:

<https://letsencrypt.org/>

Ви можете прочитати про nginx тут:

<https://nginx.org/en/>

Вимоги
============

Операційна система
----------------

Цей посібник розповідає про Debian, але ці інструкції можна легко адаптувати
для інших дистрибутивів, або FreeBSD. Завжди читайте посібник!

IP-адреси
------------

*Одна* адреса IPv4 і *одна* адреса IPv6 для хоста. Обидві IP-адреси мають
бути загальнодоступними та доступними для ping з Інтернету.

Переадресація портів також прийнятна.

Порти
-----

Ви також повинні переконатися, що порти 80 і 443 *відкриті*. IP-маршрутизація та
фільтрація пакетів виходять за рамки цієї статті, але ви можете переглянути
[розділ маршрутизатора](../router/index.uk.md), щоб отримати додаткові вказівки.

DNS
---

Вам потрібні вказівники `A` (IPv4) і `AAAA` (IPv6) у вашій конфігурації DNS для
вашого доменного імені, які вказують на адресу IPv4 і IPv6 хосту, який
запускатиме ваш веб-сервер.

Ви можете розглянути [розміщення власного DNS](../dns/), використовуючи
посібники, надані Fedfree.

У цьому посібнику передбачається, що ви налаштували наступне:

* `example.com.` (голий домен) записи A та AAAA
* `www` (`www.example.com`) записи A і AAAA

Приклади записів (з файлу зони ISC BIND, який використовується
для [libreboot.org](http://libreboot.org/)):

```
libreboot.org.  IN  A    81.187.172.132
www             IN  A    81.187.172.132
libreboot.org.  IN  AAAA 2001:8b0:b95:1bb5::4
www             IN  AAAA 2001:8b0:b95:1bb5::4
```

Додатково: DNS CAA
-----------------

Ви можете налаштувати DNS CAA (авторизація центру сертифікації) для
своїх доменів. Щось подібне буде розміщено у вашому файлі зони
DNS (наведений нижче синтаксис стосується файлу зони ISC BIND):

```
example.com.    IN  CAA 0 issue "letsencrypt.org"
example.com.    IN  CAA 0 iodef "mailto:you@example.com"
```

Якщо вказано `example.com`, замініть власне доменне ім'я (також
змініть адресу електронної пошти).

Більше інформації доступно тут: \
<https://letsencrypt.org/docs/caa/>

Додаткова інформація про файли зон ISC BIND: \
[../dns/zonefile-bind.md](../dns/zonefile-bind.md)

Вказана адреса електронної пошти ідеально має збігатися з тією, яку ви надаєте certbot
під час створення нових сертифікатів. Розмістивши записи CAA у ваших файлах зони,
лише LetsEncrypt буде дозволено створювати сертифікати для доменного імені.

Установка програмного забезпечення
---------------------

Спочатку встановіть nginx. Debian пропонує такі пакунки на вибір:

* [nginx-core](https://packages.debian.org/bullseye/nginx-core)
* [nginx-light](https://packages.debian.org/bullseye/nginx-light)
* [nginx-full](https://packages.debian.org/bullseye/nginx-full)
* [nginx-extras](https://packages.debian.org/bullseye/nginx-extras)

Якщо не впевнені, виберіть `nginx-core`, оскільки ця версія за замовчуванням, вибрана віртуальним
пакетом `nginx`. Як root:

	apt-get install nginx-core

Ви також встановите certbot і openssl. Як root:

	apt-get install certbot openssl

Обмін ключами Діффі-Хеллмана
===========================

Вступ
------------

Ключ Діффі-Хеллмана використовується для
[рукостискань](https://uk.wikipedia.org/wiki/Transport_Layer_Security#Відкриття_сеансу_(рукостискання))
TLS між браузером клієнта та сервером nginx. Ви можете дізнатися більше про
Diffie-Hellman на wikipedia:

<https://uk.wikipedia.org/wiki/Протокол_Діффі_—_Геллмана>

А про TLS тут:

<https://uk.wikipedia.org/wiki/Transport_Layer_Security>

Параметри Діффі — Хеллмана
-----------------------

Виконайте цю команду:

	openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Тепер у вас має бути цей файл: `/etc/ssl/certs/dhparam.pem` - перевірте його
вміст. Ви пізніше скористаєтеся цим під час налаштування nginx.

Ці ресурси можуть виявитися корисними (прочитайте кожну сторінку/тему) щодо
розміру ключа для dhparams:

* <https://github.com/certbot/certbot/issues/489>
* <https://gnupg.org/faq/gnupg-faq.html#no_default_of_rsa4096>
* <https://www.keylength.com/en/4/>
* <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf>
* <https://github.com/certbot/certbot/issues/2080>
* Гарна сторінка, яка демонструє вплив на продуктивність 4096-бітного та 2048-бітного RSA: \
  <https://blog.nytsoi.net/2015/11/02/nginx-https-performance>

Змінювати цей ключ кожні кілька місяців було б хорошою практикою. Ви можете
зробити це, оновлючи сертифікати в certbot.

Розмір ключа в 2048 біт все ще достатньо безпечний, принаймні до ~2028 року.
Якщо ви *хочете* використовувати щось сильніше, замість цього напишіть *4096* і
використовуйте `--rsa-key-size 4096` пізніше під час запуску certbot.

Certbot
=======

Вступ
------------

Certbot реалізує протокол
[ACME](https://uk.wikipedia.org/wiki/Automatic_Certificate_Management_Environment),
який використовує LetsEncrypt, взаємодіючи з ним для створення, оновлення та
відкликання сертифікатів. Для отримання додаткової інформації зверніться до
таких ресурсів:

* <https://certbot.eff.org/>
* <https://letsencrypt.org/docs/challenge-types/>
* <https://letsencrypt.org/docs/client-options/>

Certbot є *еталонною реалізацією*, але доступні альтернативні
програми. У цьому підручнику використовуватиметься *certbot*, оскільки
Let's Encrypt рекомендує його.

По-перше, зупиніть nginx
-----------------

*Якщо у вас уже є сертифікати, ви можете пропустити цей крок.*

Насправді ми налаштуємо це *спочатку*. Коли ви інсталюєте nginx, він буде
запущений автоматично. Ви повинні зупинити це зараз:

	systemctl stop nginx

Незважаючи на те, що certbot *забезпечує* інтеграцію nginx, ми *не* будемо це
використовувати, оскільки вона не гнучка до ідеального. Натомість, ми будемо
використовувати режим *certonly* у certbot.

Створити новий сертифікат
------------------------

*Якщо у вас уже є сертифікати, ви можете пропустити цей крок.*

**СТІЙ! Перш ніж продовжити, будь ласка, переконайтеся, що DNS працює. Ви можете
спробувати зробити ping на ваш сервер на `example.com` та `www.example.com`,
де `example.com` має бути замінено на ваше справжнє доменне ім'я.**

Якщо у вас уже належним чином налаштовано DNS, ви можете буквально просто
запустити його зараз, щоб створити новий ключ.

**СТІЙ! НЕ запускайте ці команди відразу, натомість прочитайте та збережіть їх
для довідки:**

	certbot certonly -d example.com
	certbot certonly -d www.example.com

Прочитайте наступні розділи та дізнайтеся про *certbot*. Коли ви будете
готові продовжити, виконайте наведені вище команди (адаптовані для ваших цілей).

Спочатку прочитайте посібник!
----------------------

Спочатку прочитайте весь посібник із certbot:

<https://eff-certbot.readthedocs.io/en/stable/using.html>

OCSP Must-Staple
----------------

**MARNING: LetsEncrypt's OCSP service is being shut down.**

Earlier versions of this guide recommended setting OCSP Must Staple,
using the `--must-staple` argument in `certbot`.

If you've previously used this option, you must *revoke* your certificate
and then re-issue it, without OCSP Must Staple enabled.

Otherwise, renewals via certbot would be rejected and your site would go
offline.

See: <https://letsencrypt.org/2024/12/05/ending-ocsp/>

Розміри ключа RSA
-------------

В certbot розмір за замовчуванням становить 2048-біт. Якщо ви
згенерували 2048-бітний `dhparam.pem`, вам варто використовувати розмір RSA
2048-біт в certbot так само. *Якщо ви вказали 4096-біт, тоді вам варто ставити
його в certbot.*

Ви можете передати `--rsa-key-size 4096` в certbot для більшого розміра ключа в
4096-біт, але будь ласка майте на увазі вимоги ефективності (в особливості на
серверах з високим трафіком).

Розмір ключа RSA в 2048-біт є досі ідеально прийнятним, приблизно до ~2028 року.
Деякі з заснованих на еліптичній кривій шифрів, які ви налаштуєте в
nginx, для TLS, мають також еквивалентну силу в RSA 7680-біт RSA.

Режим certonly
-------------

Коли certbot генерує сертифікат, він спитає чи ви не хочете розгорнути
тимчасовий веб-сервер (наданий certbot), або розмістити файли в директорії
webroot (яка надана вашим поточним httpd, в цьому випадку nginx).

Це тому що LetsEncrypt, через протокол ACME, проводить верифікацію того, що
хостова машина, яка виконує `certbot` з тою самою IP-адресою, яка вказана A/AAAA
записами в файлі зони DNS, для даного домена. Вона розмістить файли в
директорії, відносній до вашого *кореня документів*, показуючи, що ви справді
маєте владу на хостом. Це виконується в точності з метою аутентифікації.

Ви *не* мусите зупиняти nginx кожного разу. Ви тільки зробили це в якості заходу
для першого разу, але ми пізніше налаштуємо certbot для роботи *в режимі
certonly*, але з працюючим nginx; зупинка nginx *не* буде необхідна, коли
поновлюєте сертифікати. Більше про це пізніше.

Створення сертифікатів першого разу
-------------------------------

Якщо це ваш перший раз використання certbot на цьому сервері, certbot спитає
вас інші питання, такі як:

* електронна адреса
* попросить вас прочитати умови сервіса та прийняти
* поділитись вашою електронною адресою з EFF (**кажіть НІ**)

Якщо все пройшло добре, certbot скаже вам, що це виконано успішно.

Чому виконувати certbot двічі?
----------------------

Ви можете помітити, що я виконала двічі:

* `-d example.com`
* `-d www.example.com`

Це в вашій відповідальності. Ви *могли* виконати все за один підхід:

	certbot certonly -d example.com -d www.example.com

Однак, в цьому екземплярі, це значило би, що ви маєте обидва доменних імені
(які технічно різні домени) керованими одним набіром ключів. Коли це може
здаватись ефективним, це може виявитися головним болем пізніше.

Переконайтесь, що сертифікати існують
----------------------------------

Проведіть перевірку всередині цієї директорії: `/etc/letsencrypt/live`

Ви маєте тепер бачити директорії для `example.com` та `www.example.com`, яким
не був би ваш домен.

ЗРОБІТЬ РЕЗЕРВНУ КОПІЮ
----------

ПЕРЕКОНАЙТЕСЬ, що завжди тримаєте резервні копії `/etc/letsencrypt`, на
зовнішньому пристрою для накопичення. Використання `rsync` рекомендовано, для
резервних копій, оскільки він керує резервним копіями інкрементами
і загалом є доволі міцним. Зверніться до сторінки man `rsync` за інформацією.

Хоча це може не бути легким для сприйняття, з виводу certbot, тепер ви матимете
обліковий запис на Let`s Encrypt, як означено згенерованим набором ключів, і
втрата їх може бути головним болем пізніше, оскільки це може перешкодити
аутентифікації, особливо під час поновлення ключів.

Пояснення конфігураційних файлів Nginx
==============================

Пройдіть до директорії в `/etc/nginx`. Всередині цієї директорії ви побачите
багато файлів та піддиректорій.

Debian надає документацію для конфігураційних файлів за замовчуванням
всередині `/etc/nginx`, про який ви можете прочитати тут: \
<https://wiki.debian.org/Nginx/DirectoryStructure>

Більш загальна документація, конкретна для Debian, може бути знайдена тут: \
<https://wiki.debian.org/Nginx/>

Коментарі в конфігураційних файлах nginx
------------------------------

Коли ви бачите рядки, які починаються зі знаком `#`, будь ласка, знайте, що це є
*коментарі*. Вони не змінюють ніяку поведінку; натомість, вони використовуються
для вимкнення частин конфігураційного файлу або для надання анотації.

Для прикладу, якщо наступний рядок конфігураційного файлу було закоментовано
подібним чином:

```
	# gzip on;
```

Для розкоментування цього рядка, та увімкнення його, ви би змінили це на:

```
	gzip on;
```

Це є важливим, щоб всі рядки конфігураційного файлу закінчувалися символом `;`,
як ви побачите в наступних прикладах конфігураційних файлів.

/etc/nginx/nginx.conf (за замовчуванням)
---------------------

Відкрийте цей файл, щоб ви могли вивчати його. Це важливо, щоб ви познайомилися
з конфігурацією за замовчуванням, щоб ви знали те, що робите пізніше, коли
ви будете вчитися (з Fedfree), що змінювати.

Це є головним конфігураційним файлом для nginx. Nginx має їх власну
документацію, яка пояснює те, що кожний запис означає, але Debian має свою власну
конфігурацію за замовчуванням, тому є необхідним навчити вас *його* конфігурації.
Давайте пройдемо через деякі із записів тут, щоб навчити вас про те, що вони
означають:

* `user www-data;`: це визначає, що користувач `www-data` є тим, що виконує
  процеси nginx. Користувач `www-data` по більшості властивий Debian. Більше
  інформації: <https://nginx.org/en/docs/ngx_core_module.html#user>
* `worker_processes auto;`: це визначає кількість потоків, на яких nginx
  працює. Налаштування `auto` означає, що він буде використовувати загальну
  кількість ядер/потоків на вашому ЦП. Ви могли би зробити, щоб він виконувався
  на обмеженому числі потоків, але ми залишемо це в спокої. Більше інформації:
  <https://nginx.org/en/docs/ngx_core_module.html#worker_processes> - ви могли
  би встановити це на значення *нижче*, ніж кількість фізичних ядер ЦП, якщо
  ви вимагаєте ядра для чогось відмінного від http, на серверах з високим
  трафіком.
* `pid /run/nginx.pid;`: це є шлях до файлу, де nginx буде містити його
  ID процесу. Директорія `/run` це стандартне місце, де процеси в
  Linux визначають номер, для будь-якого процесу, який виконується. Ви можете
  вивчити про директорію `/run` тут:
  <https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s15.html>
* `include /etc/nginx/modules-enabled/*.conf;`: Це може містити конфігураційні
  файли, які ви можете використовувати, щоб увімкнути конфігурації. Це не суворо
  необхідно, і директорія `modules-enabled` є порожньою за замовчуванням,
  щонайменш в пакеті nginx Debian.

Тепер, ми бачимо цей блок:

```
events {
	worker_connections 768;
	# multi_accept on;
}
```

^ Директива `worker_connections` визначає скільки разів nginx може розгалудитись.
Кожне розгалудження може впоратися з великим числом одночасних з'єднань. 768 це
приємне консервативне число, для типових специфікацій апаратного забезпечення в
ці дні, але ви могли би насправді встановити це на вище число, якщо ваша машина
може впоратися з цим. Nginx керує HTTP підключеннями паралельно, на будь-якій
кількості потоків.

Директива `multi_accept` закоментована та налаштування за замовчуванням `off`.
Коли встановлено на `on`, nginx буде керувати більше одного підключення
одночасно, на worker thread. В основному, ви можете вважати в цьому налаштуванні,
що ваш сервер може керувати 768 одночасних з'єднань в будь-який даний час. Знову,
ви можете покрутити все це, засновуючись на тому, з чим ваше апаратне забезпечення
може впоратися. Значення за замовчування є дуже консервативними і мають працювати
приємно на більшості апаратного забезпечення.

Якщо ви отримаєте дуже багато трафіка до вашого сайту, ви могли би підвищити
число для налаштування `worker_connections`, та увімкнути `multi_accept`. Це
ваша справа.

Кількість підключень загалом підраховується числом worker processes, що
помножено на максимальне число worker connections. В нашому випадку,
worker processes встановлено на auto; вважайте, що ми маємо ЦП з двома ядрами,
де ми потім вважаємо, що 1536 підключень можливо в будь-який даний момент.

Якщо ми вважаємо, що кожен запит займає 10 секунд на обслуговування (безстрашне
припущення, передбачаючи, що це можливо буде менше), і що ми маємо 1536
підключень в будь-який даний момент, це буквально *мільйон щоденних відвідувачів
сайта*. Якщо ви тільки отримуєте декілька тисяч відвідувачів сайта щодня, тоді
налаштування за замовчуванням насправді надлишкове. Вам варто залишити їх, або
інакше докрутити, якщо необхідно.

Тепер ми пересуваємося до блока `http` під цим. Тут ми вставимо дуже багато в
статтю, але потім розіб'ємо її на коментарі під кожною частиною, кажучи вам
що робить кожна частина:

```
http {

	##
	# Basic Settings
	##

	sendfile on;
```

^ На традиційному POSIX, програми керують даними з комбінацією `read()` та
`write()`. Функція `read()` копіює вміст файлу в пам'ять, і `write()` записує
його назад (з пам'яті) до файлу. Іншими словами, введення/виведення виконується
в користувацькому просторі.

З директивою `sendfile` увімкненою, nginx буде використовувати функцію `sendfile()`
в ядрі Linux. Це *може* також працювати в системах FreeBSD, але Linux може
уникнути буферізації в пам'ять та з пам'яті, коли просто копіюються файли.
В цьому випадку, `sendfile()` використовуються для безпосереднього копіювання
файлу з диску до мережевого сокету, без буферізації в пам'ять. Це відбувається
в просторі ядра.

Цій опції варто бути *вимкненою*, якщо ви плануєте виконувати reverse proxy
в nginx, але в іншому випадку вона має бути залишена увімкненою, для оптимізації
ефективності.

Більше інформації на цих сторінках:

* Linux: <https://man7.org/linux/man-pages/man2/sendfile.2.html>
* FreeBSD: <https://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2>
* OpenBSD: не має `sendfile()`, тому директива nginx `sendfile` є безкорисною
  тут.

ПРИМІТКА: Якщо ви використовуєте фільтр, такий як gzip(для стиснення сторінок),
sendfile не працюватиме і nginx повернеться до використання за замовчуванням
нормальних `read()` та `write()` буфера. Ви маєте балансувати хвилювання
ефективності, беручи в облік ЦП, диск та пропускну здатність. Nginx дає вам
змогу підкручувати, залежно від вашого випадку використання, тому вам варто
адаптувати до вашого оточення, що вам необхідно.

Директива `sendfile` покрита в більших подробицях тут:
<https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/>

Не увімкнено в конфігураційному файлі nginx Debian за замовчуванням:
`sendfile_max_chunk`. Щоб не дати комусь з дуже швидким інтернет-з'єднанням
відібрати worker process, ви могли би додати рядок під цим, наприклад:

	sendfile_max_chunk 5m; # один виклик sendfile() тільки передасть 5Мбайт

Знову, підкручуйте відповідно до ваших власних потреб. Nginx *дає вам
підкручувати речі*.

```
	tcp_nopush on;
```

^ Ця опція стосується MTU та MSS вашої мережі. *MTU* означує максимальний
розмір пакетів в вашій мережі, що вимірюється в байтах (на типовій PPPoE
мережі це могло би бути 1492 або 1500, якщо jumbo-кадри підтримуються). MTU це
скорочення від *Maximum Transmission Unit*.

Якщо пакет перевищує розмір MTU, він стане фрагментованим, відправляючи частину
його в новому пакеті. Це керується автоматично, вашим роутером.

MSS (Maximum Segment Size) означено в заголовку TCP, для будь-якого даного
підключення в Інтернеті; він означує найбільший розмір, в байтах, *даних*,
якій може бути відправлено в одному сегменті TCP, де *сегмент* складається з
заголовка та частини з даними. Це *той* контекст, в якому ми найбільше
зацікавлені.

Директива `tcp_nopush` робить, щоб nginx *чекав* допоки частина з *даними* не
заповниться, згідно з MSS правилом, перед відправленням, таким чином щоб багато
даних могло бути відправлено одночасно, замість виштовхування додаткових пакетів.

Стосується: `tcp_nodelay`, в той час як не встановлено тут, може також бути
встановлено. Якщо встановлено, останній пакет буде відправлено миттєво. 

Інформація:

* <https://uk.wikipedia.org/wiki/TCP>
* <https://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nopush>
* <https://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nodelay>

```
	types_hash_max_size 2048;
```

^ Розмір hash table, зберігаючої типи MIME, в байтах. Консервативне значення
за замовчуванням; ви могли би розглянути підвищення його. Дивіться:
<https://nginx.org/en/docs/http/ngx_http_core_module.html#types_hash_max_size>

```
	# server_tokens off;
```

^ Вам варто *вимкнути це налаштування*. Розкоментуйте цей рядок, видаляючи `#`,
таким чином, щоб це казало:

	server_tokens off;

Якщо `server_tokens` *увімкнено*, ваш сервер HTTP видаватиме інформацію
клієнтам, таку як версія сервера та операційна система. *Вимкнення*
сховає таку інформацію, роблячи складнішим для хитрих індивідуумів знати, які
вразливості ви маєте, базуючись чисто на версії сервера/операційної системи.

Більше інформації:
<https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens>

```
	# server_names_hash_bucket_size 64;
```

^ Дивіться: <https://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_bucket_size>

Залишайте це на значенні за замовчуванням. Можливі значення: 32, 64 і 128.

Якщо у вас є незвичайно довге доменне ім'я в використанні, ви могли би розглянути
підвищення цього до 128. Наприклад:

`extra.ludicrously.long.to.the.point.of.being.comically.absurd.sub.example.com`

Для `blog.johndoe.com`, налаштування за замовчуванням є чудовим.

Debian залишає це закоментованим, за замовчуванням. На 64-бітному процесорі, це
буде можливо за замовчуванням 64. Якщо не впевнені, розкоментуйте рядок і
встановіть це на 64.

Встановлення цього на 128 може негативно вплинути на ефективність системи, залежно
від вашої машини, тому залишити це на 64 здається мудрим; встановіть вище, якщо
вам необхідно.

```
	# server_name_in_redirect off;
```

^ *Залиште це вимкненим*. Могло би бути навіть розумним розкоментувати це, та
вимкнути конкретно. Коли встановлено на off, головний `server_name` (landing
сторінка за замовчуванням) не буде використана, та натомість та, що вказана в
полі "Host" заголовка запита, або IP-адреса сервера, буде використана.

За замовчуванням off у будь-якому випадку. Нам потрібно це *вимкненим*, тому що
ми будемо використовувати віртуальні хости, та перенаправлення.

Більше інформації:
<https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name_in_redirect>

```
	include /etc/nginx/mime.types;
	default_type application/octet-stream;
```

^ MIME: <https://uk.wikipedia.org/wiki/MIME_%D1%82%D0%B8%D0%BF>

Файлe `mime.types` призначає MIME-типи конкретним розширенням файлів.

Для не зазначених безпосередньо розширень файлів, директива `default_type`
за замовчуванням використана.

Наприклад: `text/html` було би розцінено в якості HTML та перетворено відповідно
вашим браузером, де `text/plain` просто був би стандартним текстовим файлом,
відтвореним відповідно в вашому браузері (це просто відобразило би необробленими
вміст файлу). Тип `application/octet-stream` є бінарним файлом, як було би
презентовано вам для завантаження (наприклад, tar-архівам не варто бути
відтвореними в якості тексту вашому браузеру).

Неправильно налаштовані MIME-типи призведуть до дивних результатів. Сервер `nginx`,
щонайменш як Debian налаштовує його, надає адекватні значення за замовчуванням.

```
	##
	# Налаштування SSL (SSL Settings)
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;
```

^ Повністю неадекватні налаштування шифрування, які ми *приберемо* пізніше
в цьому керівництві.

Директива `ssl_protocols` пояснює сама себе.

Ці директиви будуть задокументовані, пізніше в цьому керівництві.

```
	##
	# Налаштування журналювання (Logging Settings)
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;
```

^ Це має бути доволі очевидно.

Демон nginx записує до цього файлу протягом дня. На початку
нового дня, поточний журнал копіюється до `access.log.1` та `error.log.1`,
і основний пишеться свіжим.

З вашим сервером в дії, ви могли би спробувати ці команди:

	tail -f /var/log/nginx/access.log
	goaccess -f /var/log/nginx/access.log

Ви могли би також зробить tail для журнала помилок. Ці можуть дозволити вам
бачить, в режимі реального часу, доступи через демона HTTP.

```
	##
	# Налаштування Gzip (Gzip Settings)
	##

	gzip on;
```

Це налаштування, коли включено таким як зверху чином, вмикає *стиснення* даних,
відправлених клієнтом, сервером, якщо клієнт підтримує це (більшість з них
підтримує).

На *дуже повільному* серверному апаратному забезпеченні (дуже дуже дуже старих,
слабких ЦП), ви могли би *вимкнути* це, якщо пропускна здатність дозволяє.

Переважна більшість людей має залишити цю опцію *увімкненою*, особливо, якщо
вони мають ліміт даних на їх підключенні до Інтернету.

```
	# gzip_vary on;
```

^ Закоментовано, таким чином налаштування за замовчуванням (off) використано.
Якщо увімкнено, це скаже проксі проводити кешування обох звичайної та стисненої
gzip версії кожного даного файлу.

Рекомендовано *вмикати* це, *допоки* у вас немає багато пам'яті,
або у вас є багато пам'яті, але у вас є *багато файлів* і багато
відвідувачів.

Ви не маєте хвилюваться про це налаштування, допоки ви насправді не виконуєте
проксі.

Довідкову інформацію про цей та інші елементи, пов'язані з gzip, наведено
нижче: <https://nginx.org/en/docs/http/ngx_http_gzip_module.html>

```
	# gzip_proxied any;
```

^ За замовчуванням *off*. Якщо увімкнено, це вмикає стиснені відповіді, коли
використовується проксі. Дивіться:
<https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_proxied>

Якщо ви не виконуєте проксі, ви не маєте хвилюватись про це налаштування.

```
	# gzip_comp_level 6;
```

^ За замовчуванням *1*, це встановлює рівень стиснення на стиснених gzip
відповідях. Тут, ви мусите взяти на облік можливості клієнтів. Запропоноване
число *6* тут може бути добрим компромісомe. Ви побачите мало переваг у
встановленні цього на *9*, в більшості випадків.

ПРИМІТКА: nginx не кешує файли, стиснені gzip в пам'яті, тому він буде
виконуватись кожного разу, але накладні витрати gzip доволі низькі. Зі
встановленим більш низьким рівнем стиснення, ви мали би менше використання
ЦП, якщо це стало проблемою на серверах з високим трафіком.
Вам варто докрутити це, відповідно до ваших потреб.

*Подумайте про це.* Більшість файлів, що веб-сервер буде розміщувати, є
*текстовими файлами*, і текст стиснення текста виконується більш легко.
Текстові файли зазвичай малі, і тому є більше сенсу в тому, щоб стискати їх, з
точки зору циклів ЦП. Заощадження на використанні пропускної здатності легко
виміряти. З іншого боку, більшість двійкових файлів, які ви обслуговуєте,
будуть такими як зображення та відео, багато з яких уже стиснені. Отже, має сенс
вимкнути стиснення для двійкових файлів. Наприклад, стиснення (в nginx) файлу JPEG
вірогідно дасть мало переваг, з точки зору співвідношення стиснення, в той час
як марнується більше циклів ЦП. Покладатися на `read()` і `write()` також не має
сенсу для великих файлів, якщо функція `sendfile()` доступна!

Вам варто розкоментувати це, і спробувати почати зі значення *6*.

```
	# gzip_buffers 16 8k;
```

Встановіть кількість буферів для відправки на стиснену gzip відповідь, та розмір
кожного буфера. *Розмір* буфера має в ідеалі бути встановлено на той же самий
розмір, як `BUFSIZ` на вашій системі, який на більшості хостів 64-біт (щонайменш
`x86_64`) становить 8Кбайт. Число `BUFSIZ` є `#define`, наданим вашим libc, що
найбільш вірогідно *GNU C Library*, якщо ви використовуєте Debian.

Якщо у вас є пакет Debian, який називається `libc6-dev`, встановленим, ви знайдете
BUFSIZ зазначеним (як кількість байт) в `/usr/include/stdio.h`. Приклад запису:

```
/* Розмір буфера за замовчуванням (Default buffer size).  */							 
#define BUFSIZ 8192
```

Рекомендовано, щоб ви *завжди* встановлювали розмір буфера таким само як `BUFSIZ`,
і визначали кількість буферів так як вимагається.

Рекомендовано, щоб ви встановлювали це, безпосередньо, і ви могли би спочатку
спробувати `16 8k`, як пропонується зверху (хоча директива закоментована, в
прикладі зверху).

Якщо ви користуєтесь хостом 32-біт, могло би бути більш ефективним використовувати
32 4Кбайт буфери натомість. Nginx замовчуванням має `32 4k` або `16 8k`, в
залежності від платформи хоста.

В деяких ситуаціях, ви могли би встановити це набагато вище, наприклад `32 8k`,
але рекомендовано використовувати більш консервативну конфігурацію (для вашого
налаштування).

```
	# gzip_http_version 1.1;
```

За замовчуванням `1.1`, який каже, що клієнт мусить підтримувати мінімальну версію
HTTP для отримання стисненої gzip відповіді. Це може бути встановлено на `1.0` або `1.1`.

Nginx також підтримує працездатність в якості сервера `HTTP/2`, який цей керівництво
пізніше покаже вам як робити, але `HTTP/1.1` клієнти сумісні з `HTTP/2` сумісними
серверами (через зворотню сумісність, в специфікації `HTTP/2`).

Рекомендовано, щоб ви безпосередньо встановили це на `1.1`, оскільки це дозволить
переконатись в максимальній сумісності. Пізніше в цьому керівництві, вам також
буде рекомендовано вимкнути клієнтське використання TLS до *версії 1.2*, а *TLS 1.2*
було вперше означено в 2008 році:

<https://www.ietf.org/rfc/rfc5246.txt>

Специфікація `HTTP/1.1` стала каноном в *1999 році*, тому більш ніж скоріше за
все, що ваші клієнти будуть підтримувати це, але з того часу, як ми будемо
вимагати обов'язкове використання TLS 1.2 або новіше, мало сенсу в `gzip_http_version`,
який встановлено на `1.0`. Специфікація `HTTP/1.1` означена, тут:

<https://www.ietf.org/rfc/rfc2616.txt>

Новіша специфікація `HTTP/2` означена тут, станом на 2015 рік:

<https://www.ietf.org/rfc/rfc7540.txt>

У нас буде більше, що сказати про це, пізніше в керівництві.

```
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
```

^ Там де gzip увімкнено, файли, які відповідають типу MIME `text/html`, завжди
надсилатимуться стиснутими, якщо клієнт це підтримує (відповідно до вашої
конфігурації типів MIME, як уже описано вище).

Дивіться: <https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_types>

Директива `gzip_types` означує додаткові файли, даних типів MIME, які ви
бажаєте стиснути в відповідях.

В прикладах зверху, MIME типи продекларовано безпосередньо. Розкоментуйте це
для увімкнення. Значення `*` продекларує, що файли *всіх* типів MIME буде
стиснено.

Значенням за замовчуванням для цього є `text/html`, який означає, що конфігурація
nginx за замовчуванням Debian стискає *тільки* `text/html`. Таким чином, вам
варто розкоментувати цей рядок. Знову, ви *не* маєте писати `text/html` тут,
оскільки nginx завжди буде стискати цей тип MIME, коли gzip увімкнено.

```
	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
```

Нарешті ми дісталися до м'яса пирога:

```
	##
	# Налаштування віртуальних хостів (Virtual Host Configs)
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}
```

^ директорія `conf.d` буде містити *додаткову* конфігурацію, як бажано.
В деяких випадках, має більше сенсу модифікація головного файлу `nginx.conf`.

В налаштуванні *за замовчуванням*, наданому Debian, ця директорія є порожньою.

Хороше використання `conf.d` це коли у вас є *один* `nginx.conf`, який може бути
застосовано до багатьох хостів, але ці хости кожен застосовує їх власні
конфігурації поверх. Наприклад, ви можете бажати виконувати *reverse proxy* та
спеціальні директиви для цього (окрім тих, що надані для кожного *віртуального
хоста*) може бути розміщено всередині `conf.d`.

Точний порядок, в якому файли `conf.d` застосовуються буде *буквено-цифровим*,
та *висхідний*. З цієї причини, хорошою практикою є встановлювати префіксом
число до кожного конфігураційного файлу.

Наприклад:

* `0000-do-this-first.conf`
* `0001-do-this-second.conf`
* `0002-do-this-third.conf`

^ Директорія `sites-enabled` буде містити *символьні посилання*, які ведуть до
файлів всередині `sites-available`, яка розміщена в `/etc/nginx/sites-available`.

Основна передумова полягає в тому, що ви повинні ввімкнути або вимкнути
певні веб-сайти на основі наявності цих посилань. Принаймні так рекомендує Debian
робити це, і я схильна погодитися. Це має сенс.

Всередині `sites-available` ви знайдете файл із назвою `default`. Усередині
`sites-enabled` ви побачите, що *також* існує символічне посилання  під назвою
`default`, яке вказує на посилання в `sites-available`.

Правила ідентичні, у тому що файли/посилання `sites-enabled` завантажуються
для кожного імені в алфавітно-цифровому порядку, за зростанням. *Однак*, це абсолютно
не має значення для наших цілей, оскільки вам покажуть, як налаштувати кожне
доменне ім'я в окремому файлі, ізольовано від усіх інших конфігурацій
віртуального хосту. Наприклад, ваше доменне ім'я `domainname.com` буде визначено
в `/etc/nginx/sites-available/domainname.com`, на яке буде вказано `sites-enabled/`
і воно визначатиме всі хости для цього домену, включаючи
субдомени.

Ми розглянемо ці файли, в наступному розділі, але спочатку ще один розділ, який
ми не розглянули:

Останній блок, який ви побачите, у стандартній конфігурації nginx Debian, виглядає
приблизно так:

```
#mail {
#	   # See sample authentication script at:
#	   # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#	   # auth_http localhost/auth.php;
#	   # pop3_capabilities "TOP" "USER";
#	   # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#	   server {
#		   listen	 localhost:110;
#		   protocol   pop3;
#		   proxy	  on;
#	   }
#
#	   server {
#		   listen	 localhost:143;
#		   protocol   imap;
#		   proxy	  on;
#	   }
#}
```

^ Це стосується проксування пошти, про яке ви можете почитати тут: \
<https://docs.nginx.com/nginx/admin-guide/mail-proxy/mail-proxy/>

Nginx може діяти в якості балансира навантаження для електронної пошти, який
Fedfree міг би покрити в наступному керівництві, але ми залишемо це в самотності
зараз. Залиште це закоментованим, в даний час, допоки ви не захочете налаштувати
це власноруч пізніше.

/etc/nginx/sites-available/default
----------------------------------

У цьому файлі багато коментарів. Я збираюся показати вам його вміст,
без коментарів, щоб він не переповнював цю сторінку

В цьому файлі ви побачите:

```
server {
	listen 80 default_server;
	listen [::]:80 default_server;
	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.html index.htm index.nginx-debian.html;

	server_name _;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}
```

Блок `server {}`, як зверху, означує правила для даного імені хоста. В прикладі
зверху, ім'я *за замовчуванням* присвоєно, яке застосовується до всіх неозначених
імен хоста, які ведуть до вашого сервера nginx. Це також буде застосовано до
прямих адрес IP (набраних в браузері користувача), на яких ваш сервер nginx
слухає.

Директива `listen 80` вкаже, що цей сервер слухає на порті 80,
через IPv4.

Директива `listen [::]:80` вкаже, що цей сервер слухає на
порті 80, через IPv6.

В цих прикладах зверху, щоб бути більш точним: `default_server` стосується
ситуації, де поле `Host` не означено в запиті HTTP, або означене поле
Host стосується імені хоста, яке ми самі не налаштували.

Тому, в прикладах вище, `listen 80 default_server` означає, що nginx буде слухати
порт 80, *для неозначених імен хоста або запитів http без означеного хоста*.

Інші опції можливі, які ми будемо покривати пізніше в цьому випадку. Наприклад,
прослуховуваня порту 443 для HTTPS може бути вказано подібним чином:

```
listen 443 ssl;
listen [::]:443 ssl;	
```

Додатково, ви могли би вмикнути `HTTP/2` (працює тільки для HTTPS):

```
listen 443 ssl http2;
listen [::]:443 ssl http2;	
```

Більше про це пізніше.

Директива `server_name` визначає ім'я хоста, наприклад `boobworld.com`.
В цьому прикладі зверху, ім'я `_` використано, яке посилається на `default_server`.

Директива `root` визначить *корінь ваших документів*, який є кореневою
директорією веб-сайта, що містить вашу домашню сторінку (наприклад, `index.html`).

Інші записи та директиви, по більшості закоментовані, існують в файлі. Файл має
коментарі в собі, які мають на увазі найкращу практику налаштування *всіх* веб-сайтів в
одному файлі.

Найкраще рекомендовано, Fedfree, щоб ви *тільки* використовували файл `default`
для *landing сторінки* за замовчуванням, в тому випадку, якщо неозначене ім'я
хоста (або адреса IP) використана.

Конкретні імена хоста, як означено `server_name`, мають бути керованими в файлі
на кожне доменне ім'я. Тому файлу варто означити блоки `server {}` для кожного
хоста того доменного імені; наприклад, `boobworld.com`, `www.boobworld.com`
та `chat.boobworld.com` всім варто бути обробленими в одному файлі. Це також
включає будь-які перенаправлення, наприклад HTTP до HTTPS, www до не-www (або
не-www до www).

Блок `location` визначає правила для конкретних локацій. В цьому випадку,
жорстко закодований шлях `/`, який посилається на весь веб-сайт, використано.
Це правило є дуже розумним, і ви можете розглянути можливість використання
його на віртуальних хостах

```
		# Спочатку спробувати подати запит в якості файлу, потім
		# в якості директорії, а потім відступити назад на відображення 404.
		try_files $uri $uri/ =404;
```

Більше інформації про директиву `try_files` написано тут:
<https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files>

По суті, `try_files` найбільш розповсюджено використовується для правил
перенаправлення.

/etc/nginx/fastcgi.conf
-----------------------

Конфігурація для FastCGI. Це не буде покриватися, взагалі, цим керівництвом,
оскільки існує намір, що це та пов'язані конфігурації буде покрито
в наступному керівництві.

Цей файл використовується, коли налаштовується PHP. В конфігурації за
замовчуванням, яка надана `nginx-core` (який, як передбачається цим керівництвом,
ви встановили), FastCGI не увімкнено взагалі; цей файл тому не має значення, на
зараз.

Ви можете знайти наступний ресурс розумним: \
<https://wiki.debian.org/nginx/FastCGI>

/etc/nginx/fastcgi\_params
--------------------------

Так само.

/etc/nginx/koi-win
------------------

Дивіться: <http://nginx.org/en/docs/http/ngx_http_charset_module.html>

Опція `charset` (в `nginx.conf`) не увімкнена цим керівництво, або
Debian. Якщо увімкнена, цей файл є прикладом, що може бути встановлено. Він
визначає *кодування*, яке nginx надав би в полі `Content-Type` заголовка
відповіді.

Fedfree радить, щоб ви не хвилювались про це.

/etc/nginx/win-utf
------------------

Інший файл, який визначає кодування. Не використовується, за замовчуванням.

/etc/nginx/snippets/fastcgi-php.conf
------------------------------------

Конфігураційний файл для приклада, для увімкнення PHP. Не використовується,
за замовчуванням.

FastCGI буде покрито, в майбутньому наступному керівництві.

/etc/nginx/snippets/snakeoil.conf
---------------------------------

Безкорисна, невикористана конфігурація, яка вмикає безкорисні, самопідписані
сертифікати. Ви будете використовувати LetsEncrypt, тому не звертайте уваги.

/etc/nginx/proxy\_params
------------------------

Не використана конфігурація. Якщо проксування має бути увімкнено в nginx, цей
файл міг би бути використаним для надання конфігурації для нього.

Nginx може бути налаштовано для використання в якості сервера reverse proxy,
поштового сервера-проксі та загального UDP-проксі. Проксування не увімкнено або
налаштовано в цьому керівництві, але це може бути (буде) покрито в майбутньому
наступному керівництві.

Ви можете знайти наступні ресурси розумними:

* <https://nginx.org/en/#mail_proxy_server_features>
* <https://nginx.org/en/#generic_proxy_server_features>
* <https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html>
* <https://nginx.org/en/docs/http/ngx_http_proxy_module.html>

/var/www/html
-------------

Це є коренем документів для вашої landing сторінки, хост `default_server` як
означено `sites-available/default`.

Не рекомендовано, щоб ви розміщували *ваш* веб-сайт тут. Це найкраще
використовувати в якості landing сторінки.

Веб-сайт за замовчування це сторінка привітання nginx, яка каже вам налаштувати
ваш веб-сервер. Ви можете так само залишити це в самотності. По факту, Fedfree
запрошує вас зробити таким чином.

*Причина*, по якій ми використовуємо це в якості landing сторінки, та використовуємо
віртуальні хости для реальних веб-сайтів, така, що ми можемо тоді більш легко
знати, чи не було дане доменне ім'я неправильно налаштовано в `sites-available/`
та `sites-enabled/`.

Налаштування TLS
=================

Ми тепер налаштуємо TLS, для `https://` URL. Це рекомендовано, щоб будь-який
сучасний веб-сайт був *виключно HTTPS*, з автоматичним HTTP-до-HTTPS
перенаправленням та *HSTS* увімкненим. Це те, що ми покриємо.

/etc/nginx/nginx.conf (TLS)
---------------------

Правильність наступної конфігурації буде відрізнятись, від ваших
вимог та нових стандартів, які виходять. Вам варто регулярно перевіряти
онлайн, щоб знати, коли ці налаштування потребують змін. Ми налаштуємо, які
шифри будуть використані.

Подивіться цю секцію, в цьому файлі:

```
	##
	# Налаштування SSL (SSL Settings)
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;
```

Змініть це казати наступне:

```
	##
	# Налаштування SSL (SSL Settings)
	##

	ssl_protocols TLSv1.2 TLSv1.3;
	ssl_prefer_server_ciphers off;
	ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
	ssl_ecdh_curve secp384r1;
	ssl_session_cache shared:SSL:10m;
	ssl_session_timeout 1d;
	ssl_session_tickets off;
	ssl_stapling on;
	ssl_stapling_verify on;
	resolver 1.1.1.1 1.0.0.1 valid=300s;
	resolver_timeout 5s;
	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
	add_header X-Frame-Options DENY always;
	add_header X-Content-Type-Options nosniff always;
	ssl_dhparam /etc/ssl/certs/dhparam.pem;
```

ПРИМІТКА: опція `always` в рядку `add_header` примушує ці заголовки
бути завжди доданими, до всіх відповідей HTTP, що виходять.

Дивіться:
<https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header> - як
ви можете бачити, існують *умови*, під якими `add_header` насправді
застосовується. Ми хочемо HSTS, nosniff та x-frame-options deny завжди бути
застосованими, без різниці що!

Конфігурація зверху надасть:

* Підтримку TLS 1.2 та 1.3. З метою безпеки, старіші TLS версії *та SSL*
  не увімкнено.
* Дозвольте клієнту вибрати, який шифр вони хочуть, зі списку, висунутого
  вашим сервером nginx.
* Підтримку тільки тих шифрів, які сортуються від добрих до дуже надійних.

Ви могли би адаптувати вище, до ваших вимог. Mozilla надає зручний
та корисний *конфігуратор*, який може бути використано для докручування, яке
засновано на ваших потребах:

<https://ssl-config.mozilla.org/>

*Рекомендовано* адаптувати їх конфігураційний файл. Конфігурація вище, надана
Fedfree, базується на *проміжній* рекомендації від Mozilla на Nginx. Це
надає послідовну сумісність з більшістю браузерів.

*Сучасна* конфігурація, як зазначено Mozilla, по більшій частині не має сенсу,
щонайменш станом на цей день, 2 січня 2023 року, для більшості людей. Станом на
цей день, не існує значний проблемних питаннь, відомих з підтримкою TLS 1.2,
і вона надає добрий спосіб відступити назад для тих, хто ще має оновитись на
більш нові веб-браузери.

Щоб пояснити деякі із тих конфігурацій, зверху:

```
	ssl_protocols TLSv1.2 TLSv1.3;
```

Вмикає TLS версії 1.2 та 1.3, конкретно. Ніяких інших версій TLS не
вмикається, і старіший *SSL* вимкнено. Старіші TLS/SSL є *небезпечним*, з
багатьма відомими уразливостями (наприклад, атаки POODLE на SSLv3).

```
	ssl_prefer_server_ciphers off;
```

^ Директива `ssl_prefer_server_ciphers` означає, що власні шифри сервера
мають бути використаними, ніж клієнтські. Насправді, буде найкращим це
*вимкнути*, але підтримувати тільки безпечні шифри на першому місці; користувачі
потім може вибрати найбільш ефективний, для їх конфігурації апаратного
забезпечення.

В ці дні, більшість ЦП мають AES прискорення, яке робить шифрування в значній
мірі більш ефективним, але деякі люди на старіших ЦП можуть бажати вибрати те,
що засноване на критерії ефективності (програмного забезпечення), залежно від того,
який є найбільш оптимізованим для їхнього сценарія використання. Залежно від
вашої моделі загрози, використання сильнішого шифрування може насправді не бути
бажаним, або вигідним; наприклад, якщо ви використовуєте Tor, по більшості
переглядаючи тільки статичні сайти і не надаєте чутливих даних веб-сайтам,
це може бути повністю зайвим.

Серверу варто тільки підтримувати шифри, які сортуються від добрих до дуже
надійних. Ми покриємо це в більших подробицях, під час налаштування шифрів
пізніше.

На іншій сторіні, ваша модель загрози може полягати в тому, що ви виконуєте
безпечну базу даних деякого різновиду, і ви хочете переконатись, що всі доступи
є настільки безпечними, наскільки можливо, з меншим шансом витіку даних до загроз
(наприклад, комерційних суперників вашої компанії), тому ви могли би це налаштування
*вмикнути*, вимагаюючи клієнтів використовувати ваш набір шифрів, в конкретному
порядку переваги. Якщо це той випадок, ви могли би також захотіти вимкнути всі
версії TLS, за вийнятком останньої специфікації 1.3.

```
	ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
```

^ Список шифрів, які підтримуються, що просувається вашим клієнтам nginx. Клієнт
може вибрати з цього списку, який шифр вони бажають використовувати.

```
	ssl_ecdh_curve secp384r1;
```

Вкажіть використовувати еліптичну криву, для ECDHE шифрів, які вказано в
`ssl_ciphers`. Більше інформації доступно тут:

<https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ecdh_curve>

Ви могли би змінити це бути `auto` натомість, якщо ви бажаєте. Якщо це налаштування
використовується, nginx використовуватиме вбудований список, наданий вашою версією
OpenSSL і за замовчуванням `prime256v1` для OpenSSL старше *1.0.2*.

З читання документації nginx, виглядає так, що ці опції є рекомендованими
(nginx):

* `prime256v1`
* `secp384r1`

Обидва можуть також бути використаними, подібним чином:

```
	ssl_ecdh_curve secp384r1:prime256v1;
```

Це налаштування буде сумісним з декількома додатковими клієнтами. В цьому
прикладі, `secp384r1` є за замовчуванням.

В старіших версіях nginx, `prime256v1` було за замовчуванням, але `secp384r1` є
більш надійним.

Ця порада *стане* застарілою, в деякий момент в майбутньому. Коли займаєтесь
шифруванням, вам варто завжди робити своє власне дослідження і переконатись, що
те, яке ви маєте є *актуальним*.

```
	ssl_session_cache shared:SSL:10m;
	ssl_session_timeout 1d;
	ssl_session_tickets off;
```

^ Це стосується *сесій* TLS.

Налаштування таймаута вказує, що даній сесії варто витікти після одного
дня. Це є *консервативним* вибором, але ви могли би розглянути, щоб вона казала
`5m`, подібним чином:

```
	ssl_session_timeout 5m;
```

Це змусить її витікати після п'яти хвилин. Чим нижче тривалість, тим більше
роботи ваш сервер (та клієнти) мусять робити, але це підвищило би безпеку,
знешкоджуючи шанс компрометації однієї сесії. Тут немає нічого дійсно погано,
щоб вона була *1 день*. Ви могли би альтернативно встановити її на `60m` натомість,
для витіку сесії в 1 годину.

*Tickets* ніколи не повинні бути ввімкнені, оскільки це поставить під загрозу
*пряму секретність*. Переконайтесь, що `ssl_session_tickets` *вимкнено*. Це робить
можливим для однієї сесії бути перезапущеної пізнішою датою, і це би вимагало
набагато більшого кешу сесії.

Налаштування `ssl_session_cache` про вказання: кеш сеансів є `shared` (спільним)
між worker processes (визначено через `worker_connections`
та `worker_processes` так, як показано раніше), і що розмір кеша становить
*10Мбайт*. Це розумне значення за замовчуванням, але ви можете встановити будь-яке
значення.

```
	ssl_stapling on;
	ssl_stapling_verify on;
```

**WARNING: Older versions of this guide recommended to enable OCSP stapling,
so it told you to turn the above settings `on`. LetsEncrypt is ending OCSP
service, so you must disable OCSP stapling to avoid your websites going
offline.**

**See: <https://letsencrypt.org/2024/12/05/ending-ocsp/>**

(Ніколи НЕ використовуйте CloudFlare для жодного зі своїх розміщень. Це посилання
надано виключно з освітньою метою. Використання великих централізованих провайдерів
CDN ПОГАНО для інтернета, тому що чим більше користувачів вони отримують, тим більше
силу вони отримують, і така сила буде *завжди* об'єктом зловживання)

(хоча використання їх DNS є нормальним, для приклада знизу. Ви можете змінити
ті IP-адреси на будь-які, що захочете:)

```
	resolver 1.1.1.1 1.0.0.1 valid=300s;
	resolver_timeout 5s;
```

^ Для отримання записів OCSP. (чому nginx має знати це?
Чи не достатньо `resolvconf`?)

Дві адреси IP є публічними резолверами DNS. Ви можете змінити їх на будь-що, що
подобається. Якщо ви виконуєте свої, ви могли би використовувати свої. Ви могли
би навіть встановити локальні тут, якщо у вас є резолвери, які виконуються в
вашій локальній мережі.

```
	add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
```

^ Hypertext Strict Transport Security (HSTS) каже браузеру віддавати перевагу HTTPS,
під час отримання ресурсів на вашому веб-сайті, для числа `max-age` в секундах (в
вищенаведеній конфігурації, це становить *2 роки*), *включаючи піддомени*. Це
є корисним знешкодженням проти *атак зниження версій*.

Якщо ваш CA упаде та помре, HSTS не обов'язково зробить ваш веб-сайт
недоступним; ви можете просто знайти інший CA. Я використовую LetsEncrypt з 2015
року, відтоді як він вперше з'явився в доступності, на `lighttpd`. Я перейшла на
`nginx` в 2017. LetsEncrypt надійний, тому на вашому місці я б не хвилювалась.

Ви *мусити* завжди тримати міцні резервні копії, безпечно та легко відновлювані
вами, тому що HSTS *скрутить* вас, якщо ви втратите доступ до облікового запису
LetsEncrypt. Пам'ятайте цю мудрість:

*Найкраща* резервна копія - це та, яка вам не потрібна.

*Найгірша* резервна копія - це та, яку хотіли би, щоб була.

```
	add_header X-Frame-Options DENY;
```

^ Це каже браузерам, що ваші веб-сторінки не мають бути відображеними всередині
HTML iframe. Це може захистити проти деяких спроб фішингу, де сайт претендує
бути вами, під час виконання зловмисницького коду деякого різновиду.

Це залежить від браузера, але будь-який пристойний браузер буде поважати цей
заголовок. Більше інформації доступно тут:

<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options>

```
	add_header X-Content-Type-Options nosniff;
```

^ Якщо типи MIME налаштовано неправильно, деякі браузери можуть спробувати
виправити його та застосувати правильну поведінку, відповідно до того, що вони
вважають є правильним типом MIME. Вони могли би зробити це, дивлячись на розширення
файлу в URI, наприклад. Це називається *MIME sniffing*.

Деякі типи MIME представляють виконуваний вміст, і це потенційно могло би бути
використано для незаконних переваг зловмисників. Цей параметр заголовка інформує
браузер, що sniffing виконувати не слід.

Більше інформації доступно тут:
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options>

```
	ssl_dhparam /etc/ssl/certs/dhparam.pem;
```

^ Ця директива перезаписує слабкіші значення за замовчуванням OpenSSL, віддаючи
вподобання вашим згенерованим ключам Diffie Hellman, які ви створили раніше в
цьому керівництві.

OCSP stapling (на доменне ім'я)
=============

Що це таке?
-----------

Коли ваш браузер отримує доступ до веб-сайту, він повинен знати, чи закінчився
термін дії даного сертифіката чи його була відкликано. Історично це робилося за
допомогою *Списку відкликаних сертифікатів* (CRL), але це було практично лише на
початку, коли Інтернет був набагато меншим. У наші дні такі файли були б занадто
великими для завантаження, що робить HTTPS непрактичним, оскільки вам потрібно
буде мати інформацію про кожен веб-сайт.

[Online Certificate Status
Protocol](https://uk.wikipedia.org/wiki/Online_Certificate_Status_Protocol)
вирішує цю проблему, тому що ви робите запит тільки для одного запису одночасно.
Це виконується вашим браузер, який зв'язується з сервісом третіх осіб в
Інтернеті, але це має недоліки:

* Додає затримку, тому що це додаткові запити HTTP для виконання
* Відповідач OCSP стає єдиною точкою відмови; якщо вони недоступні, ваш
  браузер міг би тяжко провалитись та показати застереження.
* Гірше: ваш браузер міг би тихо провалитись, дозволяючи дозвіл до сайту. Це
  могло би відкрити вас для атаки, якщо зловмисник міг би вимкнути службу OCSP
  за допомогою DDoS-атаки, щоб вимкнути перевірку, після того як вони успішно
  надали вам шахраюватий сертифікат.

Одним рішенням для *вашого* HTTP-сервера є відправлення збереженого в кеші записа
OCSP, з позначкою часу, протягом рукостискань TLS. Це би обійшло небохідність для
додаткових запитів HTTP на стороні клієнта, таким чином зберігаючи час (знижуючи
затримку) та покращуючи безпеку. Це називається *OCSP stapling*.

Не тільки це швидше, та більш безпечно, але це також більш надійно з причин, які
вже названо; в додаток, це обійде багато проблемних питань під час використання
веб-порталів, подібних як в готелях чи аеропортах, де виконувана клієнтом OCSP-
перевірки часто провалюється. Це також означає, що третя сторона (служба OCSP, в
цьому випадку LetsEncrypt) не побачить ваші звички перегляду настільки просто
(існує не багато CA).

Є один недолік: наплутайте в цьому, та відвідувачі вашого сайта побачать
противну помилку, під час спроб отримати доступ до сторінок.

Конфігурація
-------------

LetsEncrypt is ending OCSP support. See:

<https://letsencrypt.org/2024/12/05/ending-ocsp/>

Please make sure *not* to enable OCSP stapling, and please also
do not pass OCSP Must Staple in certbot. Please especially make
this change if you already did it, as per older versions of this
tutorial.

More easily add TLS certificates
================================

Пізніше, ми будемо *додавати* другий веб-сайт, після того, як nginx буде піднято,
та генерувати TLS сертифікати *без* вимкнення nginx чином, подібним тому, що
ми робили раніше. Цей розділ слід дотримуватись, в підготовку до цього.

Коли сервер працює, ви не хочете вбивати активні з'єднання, особливо на
зайнятому веб-сайті, *і особливо*, якщо ви плануєте виконувати бази даних
якогось різновиду.

Раніше в цьому керівництві, ви були проінструктовані використовувати режим `certonly`
в certbot, з certbot, діючому в режимі standalone, а не в режимі webroot. Однак,
вам варто бути здатними додавити нові сертифікати TLS в той час, як nginx працює,
для нових доменних імен, які ви бажаєте додати.

/etc/nginx/sites-available/default
----------------------------------

Ваш поточний файл буде виглядати якось, подібно цьому, коли всі коментарі буде
видалено:

```
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
}
```

Подивіться на ці рядки:

```
        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
```

Перемістить директиви `root` та `index` в блок локацій, щоб ви мали
щось подібне цьому:

```
        location / {
		root /var/www/html;
		index index.html index.htm index.nginx-debian.html;
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
```

Тепер, під блоком `location /`, ви би додали спеціальне правило, тільки для
викликів LetsEncrypt ACME, через тип виклику HTTP-01:

```
	location ^~ /.well-known/acme-challenge {
		default_type "text/plain";
		root /var/www/letsencrypt;
	}
```

Усьому файлу варто виглядати подібним чином:

```
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        location / {
                root /var/www/html;
                index index.html index.htm index.nginx-debian.html;

                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        location ^~ /.well-known/acme-challenge {
                default_type "text/plain";
                root /var/www/letsencrypt;
        }       
}
```

/var/www/letsencrypt/.well-known/acme-challenge
-----------------------------------------------

*Створіть* цю директорію, від root:

	mkdir -p /var/www/letsencrypt/.well-known/acme-challenge

Відповідь виклику LetsEncrypt, в налаштуванні, яке ми використовуємо, тільки
виконується на HTTP. Це є ідеально добрим для нас, тому що ми можемо націлити
записи A/AAAA на сервер без конфігурації імен хостів під nginx, і потім виконати
certbot в режимі certonly *з вказаним webroot*, щоб нам не треба було зупиняти
nginx.

Тепер ви мусити перезавантажити nginx:

	systemctl reload nginx

Списки каталогів (індексування) вимкнено за замовчуванням, в nginx, тому вміст
вашого каталогу `acme-challenge` не буде загальнодоступним.

Додайте новий веб-сайт
=================

Остаточно, ми дійшли до додавання веб-сайта. Попередні розділи цього керівництва
вже навчили вас всьому, що маєте знати. Команди (замініть `example.com`
на ваше доменне ім'я, для якого ви зробили сертифікати TLS):

Зробіть директорію веб-сайта
----------------------

Ваш сайт буде жити в `/var/www/example.com`. Він міг би насправді жити в
будь-якій локації, тому пристосуйте відповідно до своїх власних вимог:

	mkdir -p /var/www/example.com

Створіть файл хоста nginx, для сайта:
---------------------------------------

Створіть файл:

	touch /etc/nginx/sites-available/example.com

Увімкніть веб-сайт
------------------

(ви досі будете потребувати в дійсності налаштувати сайт)

	cd /etc/nginx/sites-enabled/
	ln -s /etc/nginx/sites-available/example.com example.com

/etc/nginx/sites-available/example.com
--------------------------------------

Це файл, який ви щойно створили. Розмість цей вміст
у файлі, замінюючи `example.com` на ваше власне доменне ім'я:

```
# HTTP (простий, незашифрований)
# Автоматично перенаправлює на HTTPS,
# окрім викликів LetsEncrypt ACME
server {
	server_name 
		www.example.com example.com;

	# ви могли би додати піддомени до server_name так само
	# наприклад: server_name git.example.com www.example.com example.com;

	# ви би потім додали запис, подібний до `server_name example.com`
	# сервера знизу

	listen 80;
	listen [::]:80;

        location / {
                return 301 https://$host$request_uri;
        }

        location ^~ /.well-known/acme-challenge {
		# перезаписати правило зверху, тільки для викликів LetsEncrypt.
		# це увімкне працездатність certbot renew, без зупинення
		# або іншої реконфігурації nginx будь-яким чином

                default_type text/plain;
                root /var/www/letsencrypt;

		# в цьому випадку, правило перенаправлення 301 не застосовується, тому що
		# цей блок локації перезапише те правило
        }

}

# HTTPS: перенаправити www.example.com до example.com
server {
	server_name www.example.com;
	listen 443 ssl http2;
	listen [::]:443 ssl http2;

	ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/www.example.com/chain.pem;

	disable_symlinks on;

	return 301 https://example.com$request_uri;
}

# HTTPS: це ваша конфігурація веб-сайта насправді
server {
	server_name example.com;
	listen 443 ssl http2;
	listen [::]:443 ssl http2;

	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

	root /var/www/example.com;
	index index.html;

	disable_symlinks on;

	# розкоментуйте це, щоб вмикнути автоматичну індексацію, в іншому випадку директорії
	# індексних файлів html повернуть HTTP 403
	# НЕ вмикайте autoindex, допоки ви не є впевненими, що він потрібен, тому що
	# це потенціальна загроза безпеці в деяких обставинах

	# autoindex on;
}
```

Випробування 
=====

Тепер протестуйте ваш веб-сайт!

nginx config
------------

Перш ніж продовжити, виконайте цю команду:

	nginx -t

Це може попередити вас про будь-яку неправильну конфігурацію.

Розпочніть nginx, подібним чином:

	systemctl start nginx

curl
----

Тепер спробуйте це:

	curl -I http://example.com/

Ви маєте побачити 301 перенаправлення. Так само для `http://www.example.com`.
Обидва мають вести до `https://example.com/` та `https://www.example.com/` відповідно.

Тепер спробуйте це:

	curl -I https://www.example.com/

Ви маєте побачити 301 перенаправлення на `https://example.com/`

Тепер спробуйте:

	curl -I https://example.com/

Якщо ви не розмістили файл `index.html` в вашому корені документів, ви маєте
побачити відповідь HTTP 403. Ви маєте побачити опції HSTS та nosniff також.

Браузер
-------

Тепер спробуйте всі адреси вище в вашому браузері.

SSL Labs
--------

SSL Labs розміщує чудовий набір тестів, який може сказати вам про багато речей,
таких як: чи CAA, HSTS, TLS 1.3 та інші речі увімкнено.

Дивіться: \
<https://www.ssllabs.com/ssltest/>

Випробування IPv6
---------

Mythic Beasts мають чудовий випробувач IPv6 на їх веб-сайті. Вам варто
також випробувати це самостійно, на IPv4. Дивіться:

<https://www.mythic-beasts.com/ipv6/health-check>

Зауваження
=======

Цей розділ стосується конфігурації хоста, який ми щойно увімкнули, надаючи
цільове доменне ім'я онлайн по мережі.

Примітки про перенаправлення 301
-------------------------

В конфігурації зверху, `www.example.com` автоматично перенаправляє (через
відповідь HTTP 301) до `example.com`. Рекомендовано, щоб ви або зробили це,
або зробіть це навпаки: `example.com` перенаправляє до `www.example.com`.
Це для пошукової оптимізації (пошукові системи також віддають перевагу сайтам,
які тільки HTTPS, в ці дні).

Для не-www до www перенаправлення, просто поміняйте місцями блоки сервера HTTPS,
та адаптуйте відповідно. Для цілей SEO, не має значення, чи ви робите www до
не-www або не-www до www, але вам варто вибрати один та триматись його.

Для моїх цілей, я зазвичай віддаю перевагу, щоб основний веб-сайт виконувався на `example.com`,
замість `www.example.com`, тому що я думаю, що це виглядає набагато чистіше. Це
різниця між Pepsi та Coca Cola, тому виберіть ваше зілля.

HTTP/2
------

Ви помітите, що HTTP/2 увімкнено в конфігурації зверху, але тільки для HTTPS.
HTTP/2 вже було покрито раніше в цьому керівництві, і це вмикає багато швидкісних
плюс інших покращень над старою HTTP/1.1 специфікацією.

Символічні посилання вимкнено
-----------------

Ви також помітите, що символічні посилання вимкнео. Це означає, що символічні
посилання всередині в корені документів не будуть працювати, взагалі. Це з метою
безпеки, і ви заохочені зробити це для кожного доменного імені, яке ви розміщуєте.

Проте, можуть бути деякі ситуації, де символічні посилання бажані, тому це
виконується для хостів, а не для сервера.

Вирішення проблем
===============

Nginx
-----

Виконайте `nginx -t` для випробування конфігурації. В більшості випадків, це скаже
вам, що ви зробили неправильно.

Certbot
-------

Коли відновлюєте сертифікати з командою `certbot renew`, certbot передбачає
використовувати порт 80, тому ми налаштували простий доступ HTTP на порті 80 тільки
для викликів LetsEncrypt ACME.

Єдиний життєздатний метод перевірки вимагає незашифрований HTTP, але наш сервер
не підтримує це для веб-сайтів. Для будь-що іншого, ніж виклик ACME,
URI автоматично перенаправляються до відповідного посилання HTTPS.

Обслуговування
===========

Debian
------

В основному, просто тримайте це оновленим з останнімі виправленнями: \
<https://www.debian.org/doc/manuals/debian-faq/uptodate.en.html>

Nginx
-----

Nginx в основному пуленепробивний. Ви могли би інакше
спробувати [etckeeper](https://etckeeper.branchable.com/), який є гарним інструментом
для відстеження змін, які ви робите до конфігурацій під `/etc`.

Коли ви робите зміну конфігурацій, ви можете зробити це:

	systemctl reload nginx

Або це:

	systemctl restart nginx

Nginx є дуже потужним, та надзвичайно налаштовуваним.

OpenSSL
-------

Завжди переконуйтесь в тому, щоб виконувати останні виправлення OpenSSL. Перестворюйте
`dhparam.pem` з раніше в цьому керівництві, кожні декілька місяців. (ви могли би
робити це, за сценарієм, в якості частини автоматичного поновлення сертифікатів)

Поновлюйте сертифікати
==================

Перед поновленням перший раз, вам варто випробувати, що це буде працювати. Certbot
надає функцію випробування:

	certbot renew --dry-run --webroot -w /var/www/letsencrypt

Вам *варто* абсолютно *переконатись* в тому, що nginx працює! Для мети цього
випробування. З цим налаштуванням, тип виклику `HTTP-01` (через LetsEncrypt)
використано, і це відбувається в той час, як сервер продовжує виконуватись.

В іншому випадку, якщо все добре, просто зробіть це:

	certbot renew --webroot -w /var/www/letsencrypt
	systemctl reload nginx

Команда `reload` така, що nginx використовує будь-які нещодавно створені
сертифікати. Команда `reload` відрізняється від `restart` тим, що існуючі
з'єднання залишаються відкритими, допоки не завершаться, і нові з'єднання також
буде зроблено за старими правила, допоки нова конфігурація не буде застосована,
на кожний сайт. Таким чином, зкидання відбувається непомітно для всіх, і ваш сайт
залишаться 100% онлайн.

Якщо все добре, це має Просто Працювати. Якщо це не спрацювало, вам буде потрібно
втрутитись.

Якщо є щось, що Fedfree може зробити для покращення цього керівництва, будь ласка
зв'яжіться через сторінку зв'язку.

Автоматичне поновлення сертифікатів
=======================

Випробування
-------

*Поновлення* дуже відрізняється від створення *нового* сертифіката, і останнє
покрито в іншому розділі цього керівництва.

Насамперед, випробуйте, що ваша конфігурація працює з dry run:

	certbot renew --dry-run --webroot -w /var/www/letsencrypt

Вам варто розмістити certbot renewal на автоматичний crontab, але майте на увазі:
хоча тривалість сертифікатів становить 3 місяці (з LetsEncrypt), ви можете
створювати множинні сертифікати в різні часи, тому час може вийти з
синхронізації для кожного з них.

Тому рекомендовано виконувати `certbot renew` кожного тижня, просто на випадок.

Більш автоматизований шлях робити це є подібним цьому:

```
#!/bin/bash

certbot renew --webroot -w /var/www/letsencrypt
systemctl reload nginx

# якщо у вас також є пошта, наприклад, з сертифікатами e.g. mail.example.com
# systemctl restart postfix
# systemctl restart dovecot
```

^ Додайте вище до нового файлу в `/sbin/reloadservers`, та позначіть його виконуваним:

	chmod +x /sbin/reloadservers

ОПЦІОНАЛЬОН: додайте команду з раніше в цьому керівництві, яка згенерувала
файл `dhparam.pem`. Додайте її в сценарій вище.

Потім робіть:

	crontab -e

Додайте наступне до crontab:

```
0 0 * * 0 /sbin/reloadservers
```

Виклик HTTP-01 проти DNS-01
===========================

Проблема
-------

Дивіться: <https://letsencrypt.org/docs/challenge-types/>

За замовчуванням, `certbot renew` буде використовувати тип виклику `HTTP-01`, який
буде вимагати, що certbot *прив'язався* до порту 80. Це є проблемою, оскільки nginx
слухає на порту 80, тому ви би отримали помилку.

Виконання цього на webroot (використовуючи `certbot certonly` натомість) буде
працювати *бездоганно*, тому що *це* вимагає порт 80 та `http://`, але ваш
веб-сервер налаштовує це так, що виклики ACME (в `/.well-known/acme-challenge`)
*не* перенаправляють.

Єдина річ, яка може використати `/.well-known/acme-challenge` це certbot,
і LetsEncrypt, який зв'язується з ним. Все інше має продовжувати перенаправляти.

DNS-01
------

Тип виклику `DNS-01` не надається, жодним шляхом, цим керівництвом.
Це згадано тут для посилання, тому що це цікава опція в будь-якому випадку.

Тип виклику `DNS-01` є практичним, якщо:

* Ви виконуєте [ваш власний авторитетний сервер імен](../dns/)
* Ви маєте його на тому самому хості, що nginx *АБО* безпечний шлях контролювати
його з хоста, який виконує nginx

Виклик `DNS-01` може бути виконано, *без* вбивства nginx. Це означає, що
відвідувачі вашого сайту не втратять їх з'єднання, не має значення наскільки
швидко. Ви би виконали `systemctl reload nginx`, після того, як всі сертифікати
поновлено. Це мусить бути зроблено *індивідуально на кожне доменне ім'я*. Це
означає, що ви потребуєте насправді бути там, вставляючи відповіді до кожного
виклику, в кожний файл зони DNS, для кожного домену... це причина, чому воно є
практичним тільки, якщо ви виконуєте ваш власний DNS.
Ви можливо могли би зробити деяке ґунфу
з [sed](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html)
та [awk](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html)
дл/ виконання роботи легко, оперуючи безпосередньо вашими файлами зони, або
локально (якщо виконуєтся на тій же самій машині, що nginx), або через ssh.

TLS-ALPN-01
-----------

Тип виклику `TLS-ALPN-01` це те, чому ми би віддали перевагу, але згідно з тією
сторінкою, воно ще не працює на nginx або certbot.

Перевагою цього методу є те, що це може бути зроблено чисто на рівні TLS, так
ми би не мусили мати безлад з правилами перенаправлення під nginx.

Коли ця опція буде життєздатною в майбутньому, вона може бути задокументованою
на Fedfree.

Додайте *другий* новий веб-сайт
=======================

Вступ
------------

Ви будете вже знати, як nginx налаштовано, на цьому моменті. В цьому новому
сценарію, ви дуже щасливі з вашим поточним веб-сайтом, але тепер ви хочете
розмістити ще один інший. Ви *можете* розмістити його на цій машині, доволі легко.
Розміщення численних веб-сайтів на одній машині є тривіальним.

Це керівництво провело вас черзе налаштування Nginx з *SNI* для цілей TLS, тому
це доволі можливо. Більшість/всі сучасні браузери підтримують SNI в ці дні.
SNI (Server Name Indication) є функцією в сучасному TLS, яка дозволяє клієнтам
отримувати доступ через різні сертифікати, базуючись на тому, що вказано у
заголовку Host. Дивіться:

<https://uk.wikipedia.org/wiki/Server_Name_Indication>

НЕ налаштовуйте ім'я хосту спочатку
-----------------------------------

Пам'ятаєте сайт `default_server`, в `/var/www/html`?

Якщо ви бажаєте направити новий домен (`www.newdomain.com` та `newdomain.com`)
до вашого сервера, він буде *працювати* на порту 80 через опцію `default_server`
в nginx. *Це передбачає, що ви вже не розмістили домен десь ще з HSTS, в такому
випадку ви можете просто зробити копію ключів/сертифіката до вашої нової
інсталяції*.

Ви помітите, що ми *включили* фрагмент LetsEncrypt, який вмикає метод `webroot`
для праці, через виклик `HTTP-01`. В нашому налаштуванні, виклик `HTTP-01`
буде *працювати* бездоганно, допоки цільовий домен є доступним на порту 80,
*який доступний* в нашій конфігурації.

Додайте новий сертифікат TLS
---------------------------

Якщо DNS налаштовано відповідно, просто зробіть це (для `newdomain.com`):

	certbot certonly --webroot --agree-tos --no-eff-email --email you@example.com -w /var/www/letsencrypt -d newdomain.com

та для `www.newdomain.com`:

	certbot certonly --webroot --agree-tos --no-eff-email --email you@example.com -w /var/www/letsencrypt -d www.domain.com

Відповідь виклику LetsEncrypt робиться через порт 80. Якщо все пройшло добре, ви
маєте мати нові файли під `/etc/letsencrypt/live/newdomain.com`
та `/etc/letsencrypt/live/www.newdomain.com`.

Тепер коли веб-сайт працюватиме пізніше, ваш crontab буде автоматично
поновлювати сертифікат.

Якщо все пройшло добре з certbot, і ви маєте новий сертифікат, ви можете просто
налаштувати нове доменне ім'я, адаптуючи ті ж самі процедури, які ви вже
проходили раніше на цій сторінці. Коли ви впевнені, що це добре, ви можете
потім зробити:

	nginx -t

Якщо nginx не повідомляє про проблеми, ви можете тоді робити це:

	systemctl reload nginx

Знову, це тільки для *додавання* свіжих сертифікатів. Для відновлення
ви будете натомість залежати від функції certbot *renew*.

Як відкликати сертифікат
===========================

Чому?
----

Якщо ви вірите, що ключ скомпрометовано, вам варто відкликати його негайно.

Альтернативно, ви могли забути щось в certbot, таке як:

* `--rsa-key-size 4096` (якщо ви хотіли це)

В цих обставинах, найкраще відкликати ключ. Certbot також спитає
те, чи ви хочете також видалити ключ (скажіть ТАК).

Якщо сертифікат відкликано та видалено, ви можете потім створити новий.

Як?
----

Вам *не* треба зупиняти nginx, але ЗРОБІТЬ ПРИМІТКУ: коли сертифікат
відкликано, якщо ви також видалили його, nginx провалиться під час перезагрузки.
Таким чином, коли ви робите це, вам варто потім зробити одну із наступних речей:

* Перезапитати новий сертифікат, на заміну кожному відкликаному
* Вимкніть цільовий домен (`www.example.com` та `example.com` на порту 443)

Команди для приклада:

	certbot revoke --webroot -w /var/www/letsencrypt --cert-path /etc/letsencrypt/live/example.com/cert.pem --key-path /etc/letsencrypt/live/example.com/privkey.pem --reason unspecified

	certbot revoke --webroot -w /var/www/letsencrypt --cert-path /etc/letsencrypt/live/www.example.com/cert.pem --key-path /etc/letsencrypt/live/www.example.com/privkey.pem --reason unspecified

Інші опції доступні для `--reason` наступні:

* `unspecified`
* `keycompromise`
* `affiliationchanged`
* `superseded`
* `cessationofoperation`

Ви можете потім створити новий сертифікат, та перезапустити nginx.

Посилання
==========

Debian
------

* Документація Debian: <https://www.debian.org/doc/>

Let's Encrypt
-------------

* Документація Let's Encrypt: <https://letsencrypt.org/docs/>
* Let's Encrypt Chain of Trust: <https://letsencrypt.org/certificates/>
* Документація Certbot: <https://eff-certbot.readthedocs.io/en/stable/>

Nginx
-----

* Апстрім документація Nginx: <https://nginx.org/en/docs/>

Веселий факт:

На момент публікації цього керівництва, власний веб-сайт Nginx не вмикнув
перенаправлення HTTP до HTTPS або HSTS, але він вам HTTPS в наявності, для всього
сайту; деякі посилання хоча призвели би назад до незашифрованого HTTP.

Наступна сторінка показує вам, як *примусити* використання HTTPS, в звичайних
веб-браузерах:

<https://www.eff.org/https-everywhere/set-https-default-your-browser>

Оптимізація виконання
-------------------------

Це могло би бути окремим керівництвом з деяких пір, але я знайшла це корисне
посилання, яке хтось зробив:

<https://github.com/denji/nginx-tuning/blob/f9f35f58433146c3af437d72ab6156b3eb8782c9/README.md>

Як зазначено автором, приклади в посиланні з сервера для розробки.
Вам не варто просто копіювати все, що ви побачите там. Адаптуйте це для вашого
налаштування. Nginx є надзвичайно потужним. Він виконує деякі з найбільших
веб-сайтів в Інтернеті.

Посилання URL зверху для конкретної ревізії керівництва в тому сховищі. Ви
можете клонувати репозиторій подібним чином, для отримання останньої ревізії:

	git clone https://github.com/denji/nginx-tuning

Метою керівництва Fedfree є просто те, щоб ви почали працювати. Дуже заохочується,
щоб ви погралися з вашим налаштування, допоки воно не виконує точно те, що
ви хочете його робити.

Почесна згадка: ETags
-------------------------

Заголовок HTTP `ETag` відправлено за замовчуванням, в nginx, для статичних
ресурсів, таких як сторінки HTML.

Оскільки це не було згадано десь в конфігурація за замовчуванням Debian, це
означає, що це увімкнено. Ви можете дізнатись більше про це тут:

<https://uk.wikipedia.org/wiki/HTTP_ETag>

І тут:

<https://nginx.org/en/docs/http/ngx_http_core_module.html#etag>

Ви могли би хотіти безпосередньо увімкнути це, просто на випадок, якщо nginx колись
змінить значення за замовчуванням на *off* у майбутньому. Це є корисною оптимізацією
виконання, тому що уникає повторної відправки тіє самої немодифікованої сторінки,
якщо клієнт вже побачив та зберіг її в кеш.

Клієнти, які зберігають в кеш, будуть зберігати це значення ETag, і коли запитують
ресурс, включати їх збережене значення ETag в запит; якщо nginx бачить, що локальна
версія має той самий ETag, він відправляє назад повідомлення`HTTP 304 Not Modified`
до клієнта, а не вміст запитуваного файлу.

Використання ETags та стиснення Gzip, як увімкнено цим керівництвом, збереже вам
багато пропускної здатності. Розважайтеся!

PS: Ви могли би прочитати онлайн, що ETags є небезпечними, але насправді вони не
є таким, і ця стаття пояснює з якої причини: \
<https://www.pentestpartners.com/security-blog/vulnerabilities-that-arent-etag-headers/>

Проблемне питання з ETags це якщо ви також використовуєте спільне використання
NFS, на дійсно смішно старих версіях NFS, коли inode файлів використовувалися
як обробники; якби inode був відомий, він міг би (у цих старих версіях) дозволити
доступ до файлу без авторизації... у NFS, якщо ви використовуєте його версію з
1989 року.

Nginx *не використовує inode, коли створює ETag!*

Логіка Nginx, яка керує створенням ETag може бути знайдена тут: \
<https://raw.githubusercontent.com/nginx/nginx/641368249c319a833a7d9c4256cd9fd1b3e29a39/src/http/ngx_http_core_module.c>

Подивіться в функцію named, в тому файлі:

```
ngx_int_t
ngx_http_set_etag(ngx_http_request_t *r)
```

Ви побачите все це там. Fedfree радить, щоб ви залишили ETags *увімкненим*.
Реалізая ETag Nginx є абсолютно безпечною, в конфігурації, яку
Fedfree надав для вас.

Це все.
